/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 * 
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 * 
 * Last Modified: 2015-11-27 17:04:42
 ******************************************************************************/
package cn.cmcc.online.smsapi.sdk.db;

import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.content.ContentValues;
import cn.cmcc.online.smsapi.sdk.Iservice.OnlineUpdateCycleConfigInterface;
import cn.cmcc.online.smsapi.sdk.Iservice.XyCallBack;
import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.db.entity.MenuInfo;
import cn.cmcc.online.smsapi.sdk.db.entity.SysParamEntityManager;
import cn.cmcc.online.smsapi.sdk.db.entity.pubinfo.PubInfoManager;
import cn.cmcc.online.smsapi.sdk.dex.DexUtil;
import cn.cmcc.online.smsapi.sdk.log.LogManager;
import cn.cmcc.online.smsapi.sdk.net.NetUtil;
import cn.cmcc.online.smsapi.sdk.net.util.ServerUtil;
import cn.cmcc.online.smsapi.sdk.util.FileUtils;
import cn.cmcc.online.smsapi.sdk.util.StringUtils;
import cn.cmcc.online.smsapi.sdk.util.XmlManager;
import cn.cmcc.online.smsapi.sdk.util.XyUtil;

public class MenuInfoManager {

    public static final int NOTFINISH = 0;
    public static final int FINISH = 1;
    public static final String ID = "id";
    public static final String NAME = "name";
    public static final String VERSION = "version";
    public static final String URL = "url";
    public static final String STATUS = "status";// 0未下载(包括还没下载完的)，1下载完毕
    public static final String LASTLOADTIME = "last_load_time";
    public static final String UPDATETIME = "update_time";
    public static final String DELAYSTART = "delaystart";
    public static final String DELAYEND = "delayend";
    public static final String COUNT = "count";
    public static final String TABLE_NAME = "tb_menu_list";

    public static final String DROP_TABLE = " DROP TABLE IF EXISTS " + TABLE_NAME;
    public static final String CREATE_TABLE = "create table  if not exists " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY," + NAME + " TEXT," + VERSION + " TEXT," + URL + " TEXT," + STATUS + " INTEGER DEFAULT '0'," + UPDATETIME + " INTEGER DEFAULT '0'," + DELAYSTART + " INTEGER DEFAULT '0'," + DELAYEND + " INTEGER DEFAULT '0'," + COUNT + " INTEGER DEFAULT '0'," + LASTLOADTIME + " INTEGER DEFAULT '0' " + ")";

    public static void findMenuList(Map<String, String> extend, XyCallBack xyCallBack) {
        if (!NetUtil.checkAccessNetWork(extend)) {
            /*
             * if (xyCallBack != null) { xyCallBack.execute("-1"); }
             */
            XyUtil.doXycallBack(xyCallBack, "-1");
        } else {
            MenuInfo menuInfo = MenuInfoManager.queryMenuInfo("menuMain");
            if (menuInfo != null) {
                if (!StringUtils.isNull(menuInfo.url) && menuInfo.status == MenuInfoManager.NOTFINISH)

                {
                    // if (xyCallBack != null)
                    // {
                    // xyCallBack.execute("1");
                    // }
                    XyUtil.doXycallBack(xyCallBack, "1");

                } else {
                    updateMenuInfo(menuInfo, xyCallBack, false, extend);
                }

            }

        }
    }

    public static void findMenuList() {

        // 获取tb_menu_list里所有数据进行检查更新和检查下载
        MenuInfo menuInfo = MenuInfoManager.queryMenuInfo("menuMain");
        if (menuInfo != null) {
            checkMenu(menuInfo);
        }

    }

    public static void checkMenu(MenuInfo menuInfo) {

        if (System.currentTimeMillis() > (menuInfo.updateTime + DexUtil.getUpdateCycleByType(OnlineUpdateCycleConfigInterface.TYPE_FIND_MENU_LIST_CYCLE, Constant.weekTime))) {// 如果超过请求周期，则需要发送请求
            updateMenuInfo(menuInfo, null, true, null);
        } else {// 如果没超过周期，检查下载
            int isAuto = SysParamEntityManager.getIntParam(Constant.getContext(), Constant.AUTO_UPDATE_DATA);
            if (isAuto == 0) {
                if (NetUtil.checkAccessNetWork(1)) {
                    // 仅wifi下，下载。
                    downloadMenuInfo(menuInfo);
                }

            }

        }
    }

    public static void updateMenuInfo(final MenuInfo menuInfo, final XyCallBack callback1, final boolean isdown, final Map<String, String> extend) {
        try {

            XyCallBack callback = new XyCallBack() {
                @Override
                public void execute(Object... obj) {
                    try {

                        if (obj != null) {
                            String resutCode = obj[0].toString();
                            LogManager.d("MenuInfo", "resut_Code=",resutCode);
                            if (resutCode.equals("0") && obj.length == 2) {

                                String response = obj[1].toString();
                                MenuInfo info = parseMenuSubInfo(response);
                                if (info != null) {
                                    long nowTime = System.currentTimeMillis();
                                    if (!StringUtils.isNull(info.version) && !StringUtils.isNull(info.url) && !info.version.equals(menuInfo.version)) {
                                        // 需要下载zip包
                                        menuInfo.url = info.url;
                                        menuInfo.updateTime = System.currentTimeMillis();
                                        menuInfo.version = info.version;
                                        menuInfo.status = NOTFINISH;
                                        menuInfo.delaystart = nowTime + info.delaystart;
                                        menuInfo.delayend = nowTime + info.delayend;
                                        updateMenuInfo(menuInfo.name, menuInfo.version, menuInfo.url, menuInfo.updateTime, menuInfo.status, menuInfo.delaystart, menuInfo.delayend);
                                        /*
                                         * if(callback1!=null) {
                                         * callback1.execute("1"); }
                                         */
                                        XyUtil.doXycallBack(callback1, "1");

                                    } else {
                                        menuInfo.delaystart = nowTime + info.delaystart;
                                        menuInfo.delayend = nowTime + info.delayend;
                                        updateTime(menuInfo.name, menuInfo.delaystart, menuInfo.delayend);
                                        LogManager.d("MenuInfo", menuInfo.name,"和服务器算法一样，无需更新");
                                        /*
                                         * if(callback1!=null) {
                                         * callback1.execute("0"); }
                                         */
                                        XyUtil.doXycallBack(callback1, "0");
                                    }

                                } else {
                                    updateTime(menuInfo.name);
                                    LogManager.d("MenuInfo", menuInfo.name ,"和服务器算法一样，无需更新");
                                    /*
                                     * if(callback1!=null) {
                                     * callback1.execute("0"); }
                                     */
                                    XyUtil.doXycallBack(callback1, "0");
                                }

                            } else {
                                /*
                                 * if(callback1!=null) {
                                 * callback1.execute("-2"); }
                                 */
                                XyUtil.doXycallBack(callback1, "-2");

                            }
                        }
                    } catch (Throwable e) {
//                        e.printStackTrace();
                        /*SDK-550 hewengao 20160719 start*/
                        LogManager.e(Constant.TAG, "updateMenuInfo: ", e);
                        /*SDK-550 hewengao 20160719 end*/

                    } finally {
                        if (isdown) {
                            int isAuto = SysParamEntityManager.getIntParam(Constant.getContext(), Constant.AUTO_UPDATE_DATA);
                            if (isAuto == 0) {
                                if (NetUtil.checkAccessNetWork(extend)) {// 网络可用则下载
                                    downloadMenuInfo(menuInfo);
                                }

                            }
                        }

                    }

                }
            };

            /* SDK-504 huangzhiqiang 20160623 start */
            if (NetUtil.checkAccessNetWork(extend)) {
                String dataString = ServerUtil.getUpdatePublicInfoRequest(menuInfo.version, menuInfo.name,
                        menuInfo.status, menuInfo.count);
                if (!StringUtils.isNull(dataString)) {
                    NetUtil.executeHttpPublicRequest("", dataString, callback,
                            NetUtil.getPubNumServiceUrl() + NetUtil.UpdatePublicInfoRequest, extend);// 访问服务器获取数据
                }
            }
            updateCount(menuInfo.name, menuInfo.count);
            /* SDK-504 huangzhiqiang 20160623 end */

        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "updateMenuInfo: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }

    }

    public static void downloadMenuInfoNow(final MenuInfo menuInfo) {
        /* SDK-396 huangzhiqiang 20160418 start */
        String zipName = "duoqu_nqsql.zip";
        try {
            if (StringUtils.isNull(menuInfo.url)) {
                return;
            }
            String sqlName = "menu.sql";
            // 下载zip失败
            if(FileUtils.downFile(menuInfo.url, Constant.getFilePath(), zipName) == -1){
                LogManager.d(Constant.TAG, zipName , " 下载失败");
               return;
            }

            // 解压zip到nqsql文件里面失败
            if (!XyUtil.upZipFile(Constant.getFilePath() + zipName, Constant.getINITSQL_PATH())) {
                LogManager.e(Constant.TAG, "解压zip到nqsql文件里面失败");
                return;
            }
            String sqlPath = Constant.getINITSQL_PATH() + sqlName;
            if (!FileUtils.isFileExists(sqlPath)) {
                LogManager.d(Constant.TAG, sqlPath , "文件不存在");
                return;
            }
            insertMenuData();
            updateLastLoadTime(menuInfo.name, FINISH);// 修改下载的时间
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "downloadMenuInfoNow error:", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            try {
                // 删除zip包
                FileUtils.deleteFile(Constant.getFilePath() + zipName);
            } catch (Throwable ex) {
                /*SDK-550 hewengao 20160719 start*/
                LogManager.e(Constant.TAG, "downloadMenuInfoNow deleteFile error:", ex);
                /*SDK-550 hewengao 20160719 end*/
            }
        }
        /* SDK-396 huangzhiqiang 20160418 end */
    }

    public static void insertMenuData() {
        try {

            deletePubInfoOrNumOrMenu("pubInfo");
            deletePubInfoOrNumOrMenu("pubNum");
            deletePubInfoOrNumOrMenu("pubMenu");

            // 插入最新下载的数据
            ParseItemManager.updateNeiQianSql(Constant.getContext());

        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e("xiaoyuan", "insertMenuData error： ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    public static void downloadMenuInfo(final MenuInfo menuInfo) {
        try {

            long nowTime = System.currentTimeMillis();
            // 下载状态为未下载和时间合符要求的才会触发下载
            if (menuInfo.status == NOTFINISH && (menuInfo.delaystart <= nowTime) && (menuInfo.delayend >= nowTime)) {
                downloadMenuInfoNow(menuInfo);
            }

        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "downloadMenuInfo: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }

    }

    // 删除原始数据
    public static void deletePubInfoOrNumOrMenu(String str) {
        String tableName = "";
        if (!StringUtils.isNull(str)) {
            if (str.equalsIgnoreCase("pubInfo")) {
                tableName = PubInfoManager.PUB_INFO_TABLE_NAME;
            } else if (str.equalsIgnoreCase("pubNum")) {
                tableName = PubInfoManager.PUB_NUM_INFO_TABLE_NAME;
            } else if (str.equalsIgnoreCase("pubMenu")) {
                tableName = PubInfoManager.PUB_MENU_INFO_TABLE_NAME;
            }
            if (!StringUtils.isNull(tableName)) {
                try {
                    DBManager.delete(tableName, null, null);
                } catch (Throwable e) {
                    /*SDK-550 hewengao 20160719 start*/
                    LogManager.e(Constant.TAG, "deletePubInfoOrNumOrMenu: ", e);
                    /*SDK-550 hewengao 20160719 end*/
                }
            }
        }
    }

    // 更新下载时间
    public static void updateLastLoadTime(String name, int status) {
        try {
            ContentValues values = new ContentValues();
            values.put(LASTLOADTIME, System.currentTimeMillis() + "");
            values.put(STATUS, status + "");
            DBManager.update(TABLE_NAME, values, NAME + " = ? ", new String[] { name });
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "updateLastLoadTime error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    public static void updateCount(String name, int count) {
        try {
            ContentValues values = new ContentValues();
            values.put(COUNT, count + 1);

            DBManager.update(TABLE_NAME, values, NAME + " = ? ", new String[] { name });
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "updateCount error ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    public static void updateTime(String name) {
        try {
            ContentValues values = new ContentValues();
            values.put(UPDATETIME, System.currentTimeMillis() + "");

            DBManager.update(TABLE_NAME, values, NAME + " = ? ", new String[] { name });
        } catch (Throwable e) {
//            e.printStackTrace();
            LogManager.w(Constant.TAG, "updateTime error", e);

        }
    }

    public static void updateTime(String name, long delayStart, long delayend) {
        try {
            ContentValues values = new ContentValues();
            values.put(UPDATETIME, System.currentTimeMillis() + "");
            values.put(DELAYSTART, delayStart + "");
            values.put(DELAYEND, delayend + "");
            DBManager.update(TABLE_NAME, values, NAME + " = ? ", new String[] { name });
        } catch (Throwable e) {
//            e.printStackTrace();
            LogManager.w(Constant.TAG, "updateTime error ", e);

        }
    }

    public static void updateMenuInfo(String name, String vesion, String url, long updateTime, int status, long delayStart, long delayend) {
        try {
            ContentValues values = new ContentValues();
            values.put(VERSION, vesion);
            values.put(URL, url);
            values.put(STATUS, status);
            values.put(UPDATETIME, updateTime + "");
            values.put(DELAYSTART, delayStart + "");
            values.put(DELAYEND, delayend + "");
            DBManager.update(TABLE_NAME, values, NAME + " = ? ", new String[] { name });
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "updateMenuInfo error ", e);
            /*SDK-550 hewengao 20160719 end*/

        }
    }

    /**
     * 解析菜单
     * 
     * @param xml
     * @return
     */
    public static MenuInfo parseMenuSubInfo(String xml) {
        try {
            Document doc = StringUtils.stringConvertXML(xml, "");
            if (doc == null)
                return null;
            MenuInfo menuInfo = new MenuInfo();
            String publicInfoVersion = "";
            Element root = doc.getDocumentElement();
            NodeList list = null;
            list = root.getElementsByTagName("PublicInfoVersion");
            if (list != null && list.getLength() > 0) {
                publicInfoVersion = XmlManager.getTextContent(list.item(0));
                if (StringUtils.isNull(publicInfoVersion)) {
                    publicInfoVersion = "";
                }
            }
            menuInfo.version = publicInfoVersion;

            String downLoadUrl = "";
            list = root.getElementsByTagName("downLoadUrl");
            if (list != null && list.getLength() > 0) {
                downLoadUrl = XmlManager.getTextContent(list.item(0));
                if (StringUtils.isNull(downLoadUrl)) {
                    downLoadUrl = "";
                }
            }
            menuInfo.url = downLoadUrl;

            long delaystart = 0;
            list = root.getElementsByTagName("delaystart");
            if (list != null && list.getLength() > 0) {
                String temp = XmlManager.getTextContent(list.item(0));
                if (!StringUtils.isNull(temp)) {
                    try {
                        delaystart = Long.parseLong(temp);
                    } catch (Throwable e) {
//                        e.printStackTrace();
                        /*SDK-550 hewengao 20160719 start*/
                        LogManager.w(Constant.TAG, "parseMenuSubInfo: ", e);
                        /*SDK-550 hewengao 20160719 end*/
                    }

                }

            }
            menuInfo.delaystart = delaystart;
            long delayend = 0;
            list = root.getElementsByTagName("delayend");
            if (list != null && list.getLength() > 0) {
                String temp = XmlManager.getTextContent(list.item(0));
                if (!StringUtils.isNull(temp)) {
                    try {
                        delayend = Long.parseLong(temp);
                    } catch (Throwable e) {
//                        e.printStackTrace();
                        LogManager.w(Constant.TAG, "updateMenuInfo: ", e);

                    }

                }

            }
            if (delayend <= 0) {
                delayend = 3600 * 24 * 1000;
            }
            menuInfo.delayend = delayend;
            return menuInfo;

        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "parseMenuSubInfo: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
        return null;
    }

    /**
     * 根据名称查询
     * 
     * @param name
     * @return
     */
    public static MenuInfo queryMenuInfo(String name) {
        XyCursor cur = null;
        try {
            cur = DBManager.query(TABLE_NAME, new String[] { ID, NAME, VERSION, URL, STATUS, LASTLOADTIME, UPDATETIME, DELAYSTART, DELAYEND, COUNT }, null, null);
            if (cur != null && cur.getCount() > 0) {
                int idIndex = cur.getColumnIndex(ID);
                int nameIndex = cur.getColumnIndex(NAME);
                int versionIndex = cur.getColumnIndex(VERSION);
                int urlIndex = cur.getColumnIndex(URL);
                int statusIndex = cur.getColumnIndex(STATUS);
                int lastLoadTimeIndex = cur.getColumnIndex(LASTLOADTIME);
                int udpateTimeIndex = cur.getColumnIndex(UPDATETIME);
                int startIndex = cur.getColumnIndex(DELAYSTART);
                int endIndex = cur.getColumnIndex(DELAYEND);
                int countIndex = cur.getColumnIndex(COUNT);
                MenuInfo menuInfo = null;
                while (cur.moveToNext()) {
                    menuInfo = new MenuInfo();
                    menuInfo.id = cur.getLong(idIndex);
                    menuInfo.name = cur.getString(nameIndex);
                    menuInfo.version = cur.getString(versionIndex);
                    menuInfo.url = cur.getString(urlIndex);
                    menuInfo.status = cur.getInt(statusIndex);
                    menuInfo.lastLoadTime = cur.getLong(lastLoadTimeIndex);
                    menuInfo.updateTime = cur.getLong(udpateTimeIndex);
                    menuInfo.delaystart = cur.getLong(startIndex);
                    menuInfo.delayend = cur.getLong(endIndex);
                    menuInfo.count = cur.getInt(countIndex);
                    return menuInfo;
                }

            }
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "queryMenuInfo: ", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            XyCursor.closeCursor(cur, true);
        }
        return null;
    }

    
    // 插入一个version为-1的jar
    public synchronized static void insertOrUpdateMenuInfo(String name) {

        XyCursor xyCursor = null;
        try {

            xyCursor = DBManager.query(TABLE_NAME, new String[] { URL, VERSION }, NAME + " = ? ", new String[] { name });

            if (xyCursor != null && xyCursor.getCount() > 0) {
                // 已经有数据了，不用插入
            } else {
                ContentValues values = new ContentValues();
                values.put(NAME, name);
                values.put(VERSION, "-1");
                DBManager.insert(TABLE_NAME, values);

                // jar包不存在，需要插入数据到数据库。
            }

        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "insertOrUpdateMenuInfo: ", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            XyCursor.closeCursor(xyCursor, true);
        }

    }

    public static boolean checkMenuUpdate(MenuInfo menuInfo) {
        try {
            if (menuInfo != null && !StringUtils.isNull(menuInfo.url) && menuInfo.status == MenuInfoManager.NOTFINISH) {
                return true;
            }
        } catch (Throwable e) {
            // TODO: handle Throwable
        }

        return false;
    }
}
